package com.atguigu.gmall.seckill.consumer;

import com.alibaba.fastjson.JSONObject;
import com.atguigu.gmall.model.activity.SeckillGoods;
import com.atguigu.gmall.seckill.mapper.SeckillMapper;
import com.atguigu.gmall.seckill.pojo.SeckillOrder;
import com.atguigu.gmall.seckill.pojo.UserRecode;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.UUID;

/**
 * @Author: dongdong lau
 * @CreateTime: 2021/7/16 18:57
 * @Description: 秒杀下单的监听类
 */
@Component
public class SeckillOrderAddConsumer {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private SeckillMapper seckillMapper;

    /**
     * 监听排队信息进行秒杀下单
     * @param msg
     */
    @RabbitListener(queues = "seckill_queue")
    public void addOrder(String msg){
        // 将消息的类型转化为排队类型
        UserRecode userRecode = JSONObject.parseObject(msg, UserRecode.class);
        // 进行校验，检验该用户是否有未支付的订单
        String username = userRecode.getUsername();
        // -----用户不再会有未支付的订单，因为未支付的订单不会再发消息
//        Object o = redisTemplate.boundHashOps("SeckillOrder").get(username);
//        // 说明有未支付的订单
//        if(o != null){
//            // 修改排队状态
//            userRecode.setStatus(3);
//            // 更新用户排队状态
//            redisTemplate.boundValueOps("SeckillStatus_" + username).set(userRecode);
//            return;
//        }
        // 校验商品
        String time = userRecode.getTime();
        String goodsId = userRecode.getGoodsId();
        SeckillGoods seckillGoods = (SeckillGoods)redisTemplate.boundHashOps("SeckillGoods_" + time).get(goodsId);
        // 这个时间段这个商品编号的商品不为空才能下单，否则更新订单状态商品售罄
        if(seckillGoods != null){
            // 如果有这个商品就判断库存
//            Integer stockCount = seckillGoods.getStockCount();
            Object o = redisTemplate.boundListOps("SeckillGoodsQueue_" + goodsId).rightPop();
            // 判断库存
            if(o != null){
                // 构建订单信息
                SeckillOrder seckillOrder = new SeckillOrder();
                seckillOrder.setId(UUID.randomUUID().toString().replace("-",""));
                seckillOrder.setGoodsId(goodsId);
                seckillOrder.setNum(userRecode.getNum());
                seckillOrder.setMoney(userRecode.getNum() * seckillGoods.getCostPrice().doubleValue() + "");
                seckillOrder.setUserId(username);
                seckillOrder.setCreateTime(userRecode.getCreateTime());
                seckillOrder.setStatus("0");
                // 将订单信息存入Redis
                redisTemplate.boundHashOps("SeckillOrder_" + username).put(seckillOrder.getId(), seckillOrder);
                // 更新库存，存在超卖的情况---TODO
                Long stockNum = redisTemplate.boundHashOps("SeckillGoodsStockNum").increment(goodsId, -1);
                seckillGoods.setStockCount(stockNum.intValue());
                if (stockNum > 0){
                    // 更新库存
                    redisTemplate.boundHashOps("SeckillGoods_" + time).put(goodsId,seckillGoods);
                }else {
                    // 售罄处理，将Redis中的商品数据删除
                    redisTemplate.boundHashOps("SeckillGoods_" + time).delete(goodsId);
                    // 将商品数据同步到数据库中
                    seckillMapper.updateById(seckillGoods);
                }
                // 订单生成后，更新用户排队状态（秒杀待支付）
                userRecode.setStatus(2);
                userRecode.setMoney(Float.valueOf(seckillOrder.getMoney()));
                userRecode.setOrderId(seckillOrder.getId());
                // 更新用户排队状态
                redisTemplate.boundValueOps("SeckillStatus_" + username).set(userRecode);
                // 结束
                return;
            }
        }
        // 修改排队状态,商品售罄
        userRecode.setStatus(3);
        // 更新用户排队状态
        redisTemplate.boundValueOps("SeckillStatus_" + username).set(userRecode);
        // 商品卖完了用户还会买其他商品，所以删除用户的排队标识符
        redisTemplate.delete("SeckillUserQueue_" + username);
        return;
    }
}
